﻿
using CNative.EntityBuilder.CreateText;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using CNative.Dapper.Utils;

namespace CNative.EntityBuilder
{
    public class Config
    {
        #region static Funs
        static Config()
        {
            try
            {
                string AppAddr = System.Windows.Forms.Application.StartupPath.Trim(); //当前路径
                if (AppAddr.Substring(AppAddr.Length - 1, 1) != @"\")
                    AppAddr += @"\";
                AppAddr += System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName;

                Inipath = AppAddr + ".ini";
            }
            catch { }
        }
        #endregion
        #region vars
        /// <summary>
        /// 命名空间
        /// </summary>
        public static string NameSpace { set; get; } = "HisPro";
        /// <summary>
        /// 创建人
        /// </summary>
        public static string Creator { set; get; } = "HisPro";
        /// <summary>
        /// 文档保存路径
        /// </summary>
        public static string FilePath { set; get; } = @"C:\Users";
        /// <summary>
        /// 是否出去特殊字符
        /// </summary>
        public static bool IsClearSpecialChars { set; get; } = false;
        /// <summary>
        /// 实体类名前缀
        /// </summary>
        public static string EntitySuffix { set; get; } = "Entity_";
        /// <summary>
        /// 默认继承
        /// </summary>
        public static string BaseModel { set; get; } = "";
        public static List<string> DefaultUsing { set; get; } = new List<string>();


        public static DbMaintenanceProvider dBMetadata { set; get; } = null;
        public static CreateModel CreateModel { set; get; } = null;
        public static ICodeFirst codeFirst { set; get; } = null;
        #endregion

        #region 保存、加载配置文件信息
        public static void setDBMetadata(string dbname = "BaseDb")
        {
            dBMetadata = new DbMaintenanceProvider(dbname);
            CreateModel = new CreateModel(dBMetadata);
            //FillTypeReflectionTable(dBMetadata.DBType);
            codeFirst = new CodeFirstProvider(dbname);
        }
        public static void setCodeFirst(string dbname = "BaseDb")
        {
            //codeFirst = new CodeFirstProvider(dbname);
            codeFirst.Init(dbname);
        }
        /// <summary>
        /// 加载配置文件信息
        /// </summary>
        public static void loadConfigInfo()
        {
            //setDBMetadata("BaseDb");
            //------------------------------------------------------------------------
            XmlDocument doc = new XmlDocument();
            string xmlPath = Application.StartupPath + @"\App_config.xml";
            //如果没找到默认配置文件,则自动创建
            if (!File.Exists(xmlPath))
            {
                CreateDefaultConfigFile(xmlPath);
            }
            //加载配置文件信息
            doc.Load(xmlPath);
            try
            {
                Config.FilePath = doc.SelectSingleNode("config//file").Attributes["dir"].Value;
            }
            catch { }
            try
            {
                Config.IsClearSpecialChars = Convert.ToBoolean(doc.SelectSingleNode("config//othersettings").Attributes["ClearSpecialChars"].Value);
            }
            catch { }
            try
            {
                Config.NameSpace = doc.SelectSingleNode("config//othersettings").Attributes["NameSpace"].Value;
            }
            catch { }
            try
            {
                Config.Creator = doc.SelectSingleNode("config//othersettings").Attributes["Creator"].Value;
            }
            catch { }
            try
            {
                Config.EntitySuffix = doc.SelectSingleNode("config//othersettings").Attributes["EntitySuffix"].Value;
            }
            catch { }
            try
            {
                Config.BaseModel = doc.SelectSingleNode("config//othersettings").Attributes["BaseModel"].Value;
            }
            catch { }

            try
            {
                var References = doc.SelectSingleNode("config//References");
                if (References != null && References.HasChildNodes)
                {
                    DefaultUsing = new List<string>();
                    foreach (XmlNode item in References.ChildNodes)
                    {
                        DefaultUsing.Add(item.Attributes["Include"].Value);
                    }
                }
            }
            catch { }
        }

        /// <summary>
        /// 保存配置文件信息
        /// </summary>
        public static void saveConfigInfo()
        {
            XmlDocument doc = new XmlDocument();
            string xmlPath = Application.StartupPath + @"\App_config.xml";
            doc.Load(xmlPath);

            doc.SelectSingleNode("config//file").Attributes["dir"].Value = Config.FilePath;
            doc.SelectSingleNode("config//othersettings").Attributes["ClearSpecialChars"].Value = Config.IsClearSpecialChars.ToString();
            doc.SelectSingleNode("config//othersettings").Attributes["NameSpace"].Value = Config.NameSpace;
            doc.SelectSingleNode("config//othersettings").Attributes["Creator"].Value = Config.Creator;
            //doc.SelectSingleNode("config//othersettings").Attributes["EntitySuffix"].Value = Config.EntitySuffix;
            //doc.SelectSingleNode("config//othersettings").Attributes["BaseModel"].Value = Config.BaseModel;

            doc.Save(xmlPath);
        }

        /// <summary>
        /// 创建默认配置文件
        /// </summary>
        /// <param name="filePath"></param>
        private static void CreateDefaultConfigFile(string filePath)
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath, false, Encoding.Default))
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                sb.Append("<config>");
                sb.Append("<othersettings ClearSpecialChars=\"True\" NameSpace=\"CNative\" CodeType=\"\" Creator=\"jj\" EntitySuffix=\"Entity_\"  BaseModel=\"\"/>");
                sb.Append("<file dir=\"C:\" />");
                sb.Append("<References >");
                sb.Append("<Reference Include = \"System\" />");
                sb.Append("</References >");
                sb.Append("</config>");
                sw.Write(sb.ToString());
            }
        }

        #endregion
        //-------------------------------------------------------------------------------------------------------------------------------------------------
        #region GetTypeByDataTypeName
        /// <summary>
        /// 根据数据类型和数据源类型得到c#类型
        /// </summary>
        public static string GetTypeByDataTypeName(string sqlTypeName)
        {
            return dBMetadata.SqlDbProvider.GetCsharpTypeName(sqlTypeName);
        }
        #endregion
        #region GetEntityNameByTableName
        /// <summary>
        /// 去除表名或列名中的特殊符号
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public static string GetEntityNameByTableName(string tableName)
        {
            string rtn = "";
            //去除tableName中的特殊符号: _
            //1.去掉tableName中的T_、V_和MV_
            if (tableName.StartsWith("T_") || tableName.StartsWith("V_") || tableName.StartsWith("VP_"))
            {
                tableName = tableName.Substring(2, tableName.Length - 2);
            }
            if (tableName.StartsWith("MV_"))
            {
                tableName = tableName.Substring(3, tableName.Length - 3);
            }
            return tableName.Replace("_","");
            //2.将第一个字母大写, _ 后面的单词的第一个字母大写
            string[] tableNameArray = tableName.Split('_');
            if (tableNameArray.Length > 0)
            {
                foreach (string subName in tableNameArray)
                {
                    string tempName = subName.ToLower();
                    if (tempName.Length >= 1)
                    {
                        tempName = tempName.Substring(0, 1).ToUpper() + tempName.Substring(1, subName.Length - 1);
                    }
                    rtn += tempName;
                }
            }
            return rtn;
        }
        #endregion

        #region 设置文本中的关键字颜色
        /// <summary>
        /// 设置文本中的关键字颜色
        /// </summary>
        /// <param name="rtb"></param>
        public static void SetKeywordsColor(RichTextBox rtb)
        {
            string str = rtb.Text;if (str.IsNullOrEmpty_()) return;
            MatchCollection mc;

            #region 生成映射的哈希表
            ArrayList allKeywords = new ArrayList();
            allKeywords.Add("abstract");
            allKeywords.Add("as");
            allKeywords.Add("base");
            allKeywords.Add("bool");
            allKeywords.Add("break");
            allKeywords.Add("byte");
            allKeywords.Add("case");
            allKeywords.Add("catch");
            allKeywords.Add("char");
            allKeywords.Add("checked");
            allKeywords.Add("class");
            allKeywords.Add("continue");
            allKeywords.Add("decimal");
            allKeywords.Add("default");
            allKeywords.Add("delegate");
            allKeywords.Add("DateTime");
            allKeywords.Add("do");
            allKeywords.Add("double");
            allKeywords.Add("else");
            allKeywords.Add("enum");
            allKeywords.Add("event");
            allKeywords.Add("explicit");
            allKeywords.Add("extern");
            allKeywords.Add("false");
            allKeywords.Add("finally");
            allKeywords.Add("fixed");
            allKeywords.Add("float");
            allKeywords.Add("for");
            allKeywords.Add("foreach");
            allKeywords.Add("goto");
            allKeywords.Add("if");
            allKeywords.Add("implicit");
            allKeywords.Add("in");
            allKeywords.Add("int");
            allKeywords.Add("interface");
            allKeywords.Add("internal");
            allKeywords.Add("is");
            allKeywords.Add("lock");
            allKeywords.Add("long");
            allKeywords.Add("namespace");
            allKeywords.Add("new");
            allKeywords.Add("null");
            allKeywords.Add("object");
            allKeywords.Add("operator");
            allKeywords.Add("out");
            allKeywords.Add("override");
            allKeywords.Add("params");
            allKeywords.Add("private");
            allKeywords.Add("protected");
            allKeywords.Add("public");
            allKeywords.Add("readonly");
            allKeywords.Add("ref");
            allKeywords.Add("return");
            allKeywords.Add("sbyte");
            allKeywords.Add("sealed");
            allKeywords.Add("short");
            allKeywords.Add("sizeof");
            allKeywords.Add("stackalloc");
            allKeywords.Add("static");
            allKeywords.Add("string");
            allKeywords.Add("struct");
            allKeywords.Add("switch");
            allKeywords.Add("this");
            allKeywords.Add("throw");
            allKeywords.Add("true");
            allKeywords.Add("try");
            allKeywords.Add("typeof");
            allKeywords.Add("uint");
            allKeywords.Add("ulong");
            allKeywords.Add("unchecked");
            allKeywords.Add("unsafe");
            allKeywords.Add("ushort");
            allKeywords.Add("using");
            allKeywords.Add("virtual");
            allKeywords.Add("void");
            allKeywords.Add("while");
            allKeywords.Add("#region");
            allKeywords.Add("#endregion");

            #endregion

            #region 修改关键字颜色

            string KeyWords = "";
            for (int i = 0; i < allKeywords.Count; i++)
            {
                KeyWords += allKeywords[i].ToString() + "|";
            }
            KeyWords = KeyWords.TrimEnd(new char[] { '|' });
            mc = Regex.Matches(str, @"([_</\n \s])(" + KeyWords + @")(?=[_</\n \s])");
            SetColorToRichTextbox(rtb, mc, System.Drawing.Color.Blue);
            //修改第一个using的颜色
            rtb.SelectionStart = rtb.Text.IndexOf("using");
            rtb.SelectionLength = 5;
            rtb.SelectionColor = System.Drawing.Color.Blue;

            #endregion

            #region 修改备注颜色

            mc = Regex.Matches(str, @"///.*?\n");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.Green;
            }
            mc = Regex.Matches(str, @"/// <summary>?\n");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.Gray;
            }
            mc = Regex.Matches(str, @"/// </summary>?\n");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.Gray;
            }
            mc = Regex.Matches(str, @"///");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.Gray;
            }

            #endregion

            #region 修改类名

            mc = Regex.Matches(str, @"class [A-Za-z_][A-Za-z0-9_]*");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.LightBlue;
            }

            mc = Regex.Matches(str, @"class");
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = System.Drawing.Color.Blue;
            }

            //mc = Regex.Matches(str, @"<(.[^>]*)>");
            //foreach (Match c in mc)
            //{
            //    rtb.SelectionStart = c.Index+1;
            //    rtb.SelectionLength = c.Length-1;
            //    rtb.SelectionColor = System.Drawing.Color.LightBlue;
            //}
            #endregion
        }
        private static void SetColorToRichTextbox(RichTextBox rtb, MatchCollection mc, System.Drawing.Color color)
        {
            foreach (Match c in mc)
            {
                rtb.SelectionStart = c.Index;
                rtb.SelectionLength = c.Length;
                rtb.SelectionColor = color;
            }
        }
        #endregion

        #region INI文件
        static string Inipath = "";    //INI文件名

        /// <summary>
        /// 写INI文件
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="Value"></param>
        public static void IniWriteValue(string Key, string Value)
        {
            IniWriteValue("系统参数", Key, Value);
        }
        /// <summary>
        /// 写INI文件
        /// </summary>
        /// <param name="Section"></param>
        /// <param name="Key"></param>
        /// <param name="Value"></param>
        public static void IniWriteValue(string Section, string Key, string Value)
        {
            INIHelper.Write(Section, Key, Value, Inipath);
        }

        /// <summary>
        /// 读INI文件
        /// </summary>
        /// <returns></returns>
        public static string IniReadValue(string Key, string def = "")
        {
            return IniReadValue("系统参数", Key, def);
        }
        /// <summary>
        /// 读INI文件
        /// </summary>
        /// <returns></returns>
        public static string IniReadValue(string Section, string Key, string def = "")
        {
            return INIHelper.Read(Section, Key, def, Inipath);
        }

        ///// <summary>
        ///// 读取一个ini里面所有的节
        ///// </summary>
        ///// <returns></returns>
        //public static string[] IniGetAllSectionNames()
        //{
        //    return INIHelper.GetAllSectionNames(Inipath);
        //}
        ///// <summary>
        ///// 得到某个节点下面所有的key和value组合
        ///// </summary>
        ///// <param name="section"></param>
        ///// <returns></returns>
        //public static Dictionary<string, string> IniGetAllKeyValues(string section)
        //{
        //    return INIHelper.GetAllKeyValues(section, Inipath);
        //}
        #endregion
    }
}
